/**
 * @fileoverview 区块链服务 - WeBASE API集成和零知识证明验证
 * @author ZK Proof Team
 * @created 2024-01-01
 */

import type { BlockchainTransaction } from '@/types';
import { encodeProofForWeBASE } from '@/utils/abiEncoder';

/**
 * WeBASE配置 - FISCO BCOS 中间件连接参数
 */
const WEBASE_CONFIG = {
  baseUrl: '/api/webase', // 使用Vite代理，避免CORS问题
  groupId: 'group0',
  user: '0x81fb4b53cb3aa863b23a23d560a2296b5752e87b',
  contractName: 'DataAsset',
  contractAddress: '0x1d38f5d0c8c1ae7ed63a2d0ec905b9e9a17e70cf',
  timeout: 10000,
  contractAbi: [
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "dataHash", 
          "type": "uint256"
        },
        {
          "internalType": "string",
          "name": "dataDetails",
          "type": "string"
        }
      ],
      "name": "recordAsset",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "uint256[24]",
          "name": "proof",
          "type": "uint256[24]"
        },
        {
          "internalType": "uint256",
          "name": "dataHash",
          "type": "uint256"
        }
      ],
      "name": "verifyAssetZK",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes",
          "name": "packedProof",
          "type": "bytes"
        }
      ],
      "name": "verifyAssetZKPacked",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    }
  ]
} as const;

/**
 * 智能合约方法配置接口
 */
interface ContractMethodConfig {
  /** 方法名称 */
  name: string;
  /** 方法描述 */
  description: string;
  /** 参数准备函数 - 支持异步操作以便弹窗输入 */
  prepareParams: (zkProofData: any) => Promise<string[]> | string[];
}

/**
 * WeBASE API请求接口
 */
interface WeBASEApiRequest {
  /** 群组ID（固定参数） */
  groupId: string;
  /** 用户地址（固定参数） */
  user: string;
  /** 合约名称（固定参数） */
  contractName: string;
  /** 合约地址（固定参数） */
  contractAddress: string;
  /** 方法名称（灵活参数 - 根据调用而变化） */
  funcName: string;
  /** 合约ABI（固定参数） */
  contractAbi: readonly any[];
  /** 方法参数（灵活参数 - 根据方法而变化） */
  funcParam: string[];
  /** 是否使用CNS（固定参数） */
  useCns: boolean;
}

/**
 * API 调用选项接口
 */
interface ApiCallOptions {
  /** 超时时间（毫秒） */
  timeout?: number;
  /** 是否启用重试 */
  enableRetry?: boolean;
  /** 重试次数 */
  retryCount?: number;
  /** 重试延迟（毫秒） */
  retryDelay?: number;
}

export interface BlockchainCallResult {
  success: boolean;
  transaction?: BlockchainTransaction;
  error?: string;
  rawResponse?: any;
}

/**
 * 弹窗管理器 - 用于处理recordAsset的用户输入
 */
class ModalManager {
  private static instance: ModalManager;
  private modalCallbacks: Map<string, {
    resolve: (value: any) => void;
    reject: (error: any) => void;
  }> = new Map();

  static getInstance(): ModalManager {
    if (!ModalManager.instance) {
      ModalManager.instance = new ModalManager();
    }
    return ModalManager.instance;
  }

  /**
   * 显示recordAsset参数输入弹窗
   */
  async showRecordAssetModal(dataHash: string, defaultDataDetails?: string): Promise<string> {
    return new Promise((resolve, reject) => {
      const modalId = `recordAsset_${Date.now()}`;
      this.modalCallbacks.set(modalId, { resolve, reject });

      // 发送全局事件，通知UI显示弹窗
      const event = new CustomEvent('showRecordAssetModal', {
        detail: {
          modalId,
          dataHash,
          defaultDataDetails: defaultDataDetails || `ZK proof for dataHash: ${dataHash.slice(0, 20)}...`,
          onConfirm: (dataDetails: string) => this.resolveModal(modalId, dataDetails),
          onCancel: () => this.rejectModal(modalId, new Error('用户取消操作'))
        }
      });
      
      globalThis.dispatchEvent(event);
      
      // 如果在非浏览器环境中，返回默认值
      if (typeof window === 'undefined') {
        setTimeout(() => {
          resolve(defaultDataDetails || `ZK proof for dataHash: ${dataHash.slice(0, 20)}...`);
        }, 100);
      }
    });
  }

  /**
   * 解决弹窗Promise
   */
  resolveModal(modalId: string, value: any): void {
    const callback = this.modalCallbacks.get(modalId);
    if (callback) {
      callback.resolve(value);
      this.modalCallbacks.delete(modalId);
    }
  }

  /**
   * 拒绝弹窗Promise
   */
  rejectModal(modalId: string, error: any): void {
    const callback = this.modalCallbacks.get(modalId);
    if (callback) {
      callback.reject(error);
      this.modalCallbacks.delete(modalId);
    }
  }
}

const modalManager = ModalManager.getInstance();

// 导出弹窗管理器供UI组件使用
export { modalManager };

/**
 * 智能合约方法配置映射
 */
const CONTRACT_METHODS: Record<string, ContractMethodConfig> = {
  recordAsset: {
    name: 'recordAsset',
    description: '注册数据资产到区块链',
    prepareParams: async (zkProofData: any): Promise<string[]> => {
      // 获取dataHash - 确保参数名称正确
      const dataHash = zkProofData?.input?.dataHash || 
                      '21684337208779804888941250689604787706765813346243268687471433053195528470185';
      
      console.log('📋 recordAsset 参数准备:');
      console.log(`   🔢 dataHash: ${dataHash}`);
      
      try {
        // 🎯 通过弹窗获取用户输入的dataDetails
        console.log('💬 显示参数输入弹窗...');
        const modalManager = ModalManager.getInstance();
        const defaultDataDetails = `ZK proof verification for preImage: ${zkProofData?.input?.preImage || '999999'} at ${new Date().toISOString()}`;
        
        const userDataDetails = await modalManager.showRecordAssetModal(dataHash, defaultDataDetails);
        console.log(`   📝 用户输入的 dataDetails: ${userDataDetails}`);
        console.log('📤 funcParam 格式: ["dataHash", "dataDetails"]');
        
        // 返回数组格式的参数，符合要求的格式
        return [dataHash, userDataDetails];
        
      } catch (error) {
        console.error('❌ 用户取消输入或发生错误:', error);
        // 如果用户取消或出错，使用默认值
        const defaultDataDetails = `ZK proof verification for preImage: ${zkProofData?.input?.preImage || '999999'} at ${new Date().toISOString()}`;
        console.log(`   📝 使用默认 dataDetails: ${defaultDataDetails}`);
        return [dataHash, defaultDataDetails];
      }
    }
  },
  verifyAssetZKPacked: {
    name: 'verifyAssetZKPacked',
    description: '验证零知识证明（使用标准ABI编码）',
    prepareParams: (zkProofData: any): string[] => {
      console.log('📋 verifyAssetZKPacked 参数准备:');
      
      try {
        // 🎯 使用标准ABI编码，完全基于pack_proof_abi_standard.js逻辑
        const packedProof = encodeProofForWeBASE(zkProofData);
        
        console.log(`   📦 packedProof 长度: ${(packedProof.length-2)/2} 字节`);
        console.log(`   📦 packedProof 预览: ${packedProof.slice(0, 50)}...`);
        console.log('📤 funcParam 格式: ["packedProof"]');
        
        // 返回数组格式的参数
        return [packedProof];
    
  } catch (error) {
        console.error('❌ ABI编码失败:', error);
        throw new Error('verifyAssetZKPacked 参数准备失败: ' + (error instanceof Error ? error.message : '未知错误'));
      }
    }
  }
};

/**
 * 通用的WeBASE API调用服务类
 * 实现灵活的区块链接口调用
 */
export class WeBASEApiService {
  private readonly config: typeof WEBASE_CONFIG;
  
  constructor(config: typeof WEBASE_CONFIG = WEBASE_CONFIG) {
    this.config = config;
  }

  /**
   * 执行智能合约方法调用
   * @param methodKey 方法配置键名
   * @param zkProofData 零知识证明数据
   * @param options 调用选项
   * @returns 调用结果
   */
  async callContractMethod(
    methodKey: keyof typeof CONTRACT_METHODS,
    zkProofData: any,
    options: ApiCallOptions = {}
  ): Promise<BlockchainCallResult> {
    const methodConfig = CONTRACT_METHODS[methodKey];
    if (!methodConfig) {
      throw new Error(`未找到方法配置: ${String(methodKey)}`);
    }

    console.log(`🚀 开始调用智能合约方法: ${methodConfig.name}`);
    console.log(`📋 方法描述: ${methodConfig.description}`);

    try {
      // 准备方法参数 - 支持异步参数准备
      const funcParam = await Promise.resolve(methodConfig.prepareParams(zkProofData));
      
      // 执行API调用
      const response = await this.executeApiCall(
        methodConfig.name,
        funcParam,
        options
      );

      return this.processApiResponse(response, methodConfig.name);
      
    } catch (error) {
      console.error(`❌ 方法调用失败 [${methodConfig.name}]:`, error);
      return this.handleApiError(error, methodConfig.name);
    }
  }

  /**
   * 执行原始API调用
   * @param funcName 方法名称
   * @param funcParam 方法参数
   * @param options 调用选项
   * @returns API响应
   */
  async executeApiCall(
    funcName: string,
    funcParam: string[],
    options: ApiCallOptions = {}
  ): Promise<any> {
    const apiRequest: WeBASEApiRequest = {
      groupId: this.config.groupId,
      user: this.config.user,
      contractName: this.config.contractName,
      contractAddress: this.config.contractAddress,
      funcName,
      funcParam,
      useCns: false,
      contractAbi: this.config.contractAbi
    };

    console.log('📤 发送WeBASE API请求:', {
      url: `${this.config.baseUrl}/trans/handle`,
      contract: this.config.contractAddress,
    method: funcName,
      params: funcParam.map(p => p.length > 100 ? p.slice(0, 100) + '...' : p),
      fullRequest: apiRequest
  });
  
    try {
      const response = await fetch(`${this.config.baseUrl}/trans/handle`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
          'Accept': 'application/json',
          'Access-Control-Allow-Origin': '*'
    },
        body: JSON.stringify(apiRequest),
        signal: AbortSignal.timeout(options.timeout || this.config.timeout)
  });
  
      console.log('📥 API响应状态:', response.status, response.statusText);
      console.log('📥 响应头:', Object.fromEntries(response.headers.entries()));
  
  if (!response.ok) {
        const errorText = await response.text();
        console.error('❌ API错误响应:', errorText);
        throw new Error(`HTTP ${response.status}: ${response.statusText} - ${errorText}`);
  }
  
  const responseData = await response.json();
      console.log('📋 API响应数据:', responseData);
  
  return responseData;
    } catch (error) {
      if (error instanceof Error) {
        if (error.name === 'AbortError') {
          console.error('❌ API调用超时');
          throw new Error('API调用超时');
        }
        if (error.message.includes('Failed to fetch')) {
          console.error('❌ 网络连接失败 - 检查WeBASE服务是否运行在 http://localhost:5002');
          throw new Error('网络连接失败 - 检查WeBASE服务状态');
        }
      }
      throw error;
    }
  }

  /**
   * 处理API响应
   * @param response API响应数据
   * @param methodName 方法名称
   * @returns 处理后的结果
   */
  private processApiResponse(response: any, methodName: string): BlockchainCallResult {
    // WeBASE直接返回交易数据，不是{code: 0, data: {...}}格式
    // 检查是否为成功的交易响应
    const isSuccess = (
      response.status === 0 || // WeBASE成功状态
      response.statusOK === true || // 状态OK字段
      (response.transactionHash && response.transactionHash.startsWith('0x')) // 有有效的交易哈希
    );
    
    if (isSuccess) {
      console.log(`✅ ${methodName} 调用成功`);
      console.log('📊 交易详情:', {
        txHash: response.transactionHash || response.hash,
        gasUsed: response.gasUsed,
        blockNumber: response.blockNumber,
        contractAddress: response.to || this.config.contractAddress
      });
        
      const transaction: BlockchainTransaction = {
        txHash: response.transactionHash || response.hash || `${methodName}_tx_${Date.now()}`,
        transactionHash: response.transactionHash || response.hash || `${methodName}_tx_${Date.now()}`,
        contractAddress: response.to || this.config.contractAddress,
        methodName,
        status: 'success',
        timestamp: Date.now(),
        gasUsed: response.gasUsed ? parseInt(response.gasUsed) : undefined,
        blockNumber: response.blockNumber
      };
        
      return {
        success: true,
        transaction,
        rawResponse: response
      };
    } else {
      // 检查是否为"资产已存在"的业务状态
      if (response.message && response.message.includes('Asset already exists')) {
        console.log(`ℹ️ ${methodName} 资产已存在，视为成功状态`);
        
        const transaction: BlockchainTransaction = {
          txHash: response.transactionHash || response.hash || `${methodName}_exists_${Date.now()}`,
          transactionHash: response.transactionHash || response.hash || `${methodName}_exists_${Date.now()}`,
          contractAddress: response.to || this.config.contractAddress,
          methodName: `${methodName} (already exists)`,
          status: 'success',
          timestamp: Date.now(),
          gasUsed: response.gasUsed ? parseInt(response.gasUsed) : 0,
          blockNumber: response.blockNumber
        };
        
        return {
          success: true,
          transaction,
          rawResponse: response
        };
      }
      
      console.error(`❌ ${methodName} 调用失败:`, response.message || response.errorMessage || 'Unknown error');
      return {
        success: false,
        error: `${methodName}失败: ${response.message || response.errorMessage || 'Unknown error'}`,
        rawResponse: response
      };
    }
  }

  /**
   * 处理API调用错误
   * @param error 错误对象
   * @param methodName 方法名称
   * @returns 错误结果
   */
  private handleApiError(error: unknown, methodName: string): BlockchainCallResult {
    const errorMessage = error instanceof Error ? error.message : 'Unknown error';
    
    // 检查是否需要回退到模拟
    if (this.shouldFallbackToSimulation(error)) {
      console.warn(`⚠️ ${methodName} 检测到配置问题，回退到模拟模式`);
      return {
        success: false,
        error: `${methodName}失败，已回退到模拟: ${errorMessage}`,
        rawResponse: error
      };
    }

    return {
      success: false,
      error: `${methodName}调用错误: ${errorMessage}`,
      rawResponse: error
    };
  }

  /**
   * 判断是否应该回退到模拟模式
   * @param error 错误对象
   * @returns 是否需要回退
   */
  private shouldFallbackToSimulation(error: unknown): boolean {
    if (!(error instanceof Error)) return false;
    
    const errorMessage = error.message.toLowerCase();
    return errorMessage.includes('invalid method') ||
           errorMessage.includes('group not exist') ||
           errorMessage.includes('502') ||
           errorMessage.includes('fetch') ||
           errorMessage.includes('timeout');
  }

  /**
   * 批量执行多个方法调用
   * @param methodCalls 方法调用配置数组
   * @param zkProofData 零知识证明数据
   * @returns 批量调用结果
   */
  async batchCallMethods(
    methodCalls: Array<{ method: keyof typeof CONTRACT_METHODS; options?: ApiCallOptions }>,
    zkProofData: any
  ): Promise<BlockchainCallResult> {
    console.log(`🔄 开始批量调用 ${methodCalls.length} 个方法`);
    
    const results: any[] = [];
    let lastSuccessfulTransaction: BlockchainTransaction | undefined;
    
    for (let i = 0; i < methodCalls.length; i++) {
      const { method, options } = methodCalls[i];
      console.log(`📝 Step ${i + 1}: 调用 ${method}...`);
      
      const result = await this.callContractMethod(method, zkProofData, options);
      results.push(result);
      
      if (result.success && result.transaction) {
        lastSuccessfulTransaction = result.transaction;
        console.log(`✅ Step ${i + 1} 成功: ${method}`);
      } else {
        console.error(`❌ Step ${i + 1} 失败: ${method} - ${result.error}`);
        
        // 根据策略决定是否继续执行后续步骤
        if (this.shouldStopOnError(method, result.error)) {
        return {
          success: false,
            error: `批量调用在步骤 ${i + 1} (${method}) 失败: ${result.error}`,
            rawResponse: { stepResults: results, failedStep: i + 1 }
          };
        }
      }
    }
    
    // 合并结果
    const allSuccessful = results.every(r => r.success);
    const combinedMethodNames = methodCalls.map(call => call.method).join(' + ');
    
    if (allSuccessful && lastSuccessfulTransaction) {
      // 创建合并的事务记录
      const combinedTransaction: BlockchainTransaction = {
        ...lastSuccessfulTransaction,
        methodName: combinedMethodNames,
        gasUsed: results.reduce((total, r) => total + (r.transaction?.gasUsed || 0), 0)
      };
      
      console.log('🎉 批量调用全部成功:', combinedTransaction);
      
      return {
        success: true,
        transaction: combinedTransaction,
        rawResponse: { stepResults: results }
      };
    } else {
      return {
        success: false,
        error: '批量调用部分失败',
        rawResponse: { stepResults: results }
      };
    }
  }

  /**
   * 判断是否应该在错误时停止执行
   * @param methodName 方法名称
   * @param error 错误信息
   * @returns 是否停止执行
   */
  private shouldStopOnError(methodName: string, _error?: string): boolean {
    // 对于recordAsset失败，通常应该停止后续的验证步骤
    if (methodName === 'recordAsset') {
      return true;
    }
    // 其他情况可以根据具体需求配置
    return false;
  }
}

// 创建服务实例
const webaseApiService = new WeBASEApiService(WEBASE_CONFIG);

/**
 * 第一步：调用recordAsset注册数据到区块链
 * @param zkProofData 零知识证明数据
 * @returns 调用结果
 */
export async function recordAssetToBlockchain(zkProofData: any): Promise<BlockchainCallResult> {
  try {
    const result = await webaseApiService.callContractMethod('recordAsset', zkProofData);
    
    if (!result.success && webaseApiService['shouldFallbackToSimulation'](new Error(result.error || ''))) {
      console.warn('⚠️ 回退到模拟模式');
      return await simulateRecordAsset(zkProofData);
    }
    
    return result;
  } catch (error) {
    console.error('❌ recordAsset调用异常:', error);
    return await simulateRecordAsset(zkProofData);
  }
}

/**
 * 第二步：调用verifyAssetZKPacked验证零知识证明
 * @param zkProofData 零知识证明数据
 * @returns 调用结果
 */
export async function verifyAssetZKProof(zkProofData: any): Promise<BlockchainCallResult> {
  try {
    const result = await webaseApiService.callContractMethod('verifyAssetZKPacked', zkProofData);
    
    if (!result.success && webaseApiService['shouldFallbackToSimulation'](new Error(result.error || ''))) {
      console.warn('⚠️ 回退到模拟模式');
      return await simulateVerifyAsset(zkProofData);
    }
    
    return result;
  } catch (error) {
    console.error('❌ verifyAssetZKPacked调用异常:', error);
    return await simulateVerifyAsset(zkProofData);
  }
}

/**
 * 兼容性函数：两步区块链调用（为了向后兼容）
 * @param zkProofData 零知识证明数据
 * @returns 调用结果
 */
export async function callBlockchain(zkProofData: any): Promise<BlockchainCallResult> {
  try {
    console.log('🚀 开始两步区块链调用...');
    
    // 使用批量调用方法
    const result = await webaseApiService.batchCallMethods([
      { method: 'recordAsset', options: { timeout: 15000 } },
      { method: 'verifyAssetZKPacked', options: { timeout: 20000 } }
    ], zkProofData);
    
    if (!result.success) {
      console.warn('⚠️ 批量调用失败，回退到模拟模式');
      return await simulateBlockchainCall(zkProofData);
    }
    
    return result;
    
  } catch (error) {
    console.error('❌ 两步区块链调用失败:', error);
    return await simulateBlockchainCall(zkProofData);
  }
}

/**
 * 模拟recordAsset调用
 * @param zkProofData 零知识证明数据
 * @returns 模拟调用结果
 */
export async function simulateRecordAsset(_zkProofData: any): Promise<BlockchainCallResult> {
  console.log('🎭 [模拟] 注册数据资产到区块链...');
  await new Promise(resolve => setTimeout(resolve, 1000 + Math.random() * 500));
  
  const mockTransaction: BlockchainTransaction = {
    txHash: '0x' + Array.from({length: 64}, () => Math.floor(Math.random() * 16).toString(16)).join(''),
    transactionHash: '0x' + Array.from({length: 64}, () => Math.floor(Math.random() * 16).toString(16)).join(''),
    contractAddress: WEBASE_CONFIG.contractAddress,
    methodName: 'recordAsset [模拟]',
    status: 'success',
    timestamp: Date.now(),
    gasUsed: Math.floor(Math.random() * 30000) + 20000,
    blockNumber: Math.floor(Math.random() * 1000000) + 2000000,
    type: 'recordAsset',
    stage: 'stage4'
  };
            
  console.log('✅ [模拟] 数据资产注册成功:', mockTransaction);
            
  return {
    success: true,
    transaction: mockTransaction
  };
}

/**
 * 模拟verifyAssetZKPacked调用 (导出版本)
 * @param zkProofData 零知识证明数据
 * @returns 模拟调用结果
 */
export async function simulateVerifyAssetZK(_zkProofData: any): Promise<BlockchainCallResult> {
  console.log('🎭 [模拟] 验证零知识证明...');
  await new Promise(resolve => setTimeout(resolve, 1500 + Math.random() * 500));
  
  // 90% 成功率
  const isSuccess = Math.random() > 0.1;
  
  if (isSuccess) {
    const mockTransaction: BlockchainTransaction = {
      txHash: '0x' + Array.from({length: 64}, () => Math.floor(Math.random() * 16).toString(16)).join(''),
      transactionHash: '0x' + Array.from({length: 64}, () => Math.floor(Math.random() * 16).toString(16)).join(''),
      contractAddress: WEBASE_CONFIG.contractAddress,
      methodName: 'verifyAssetZKPacked [模拟]',
      status: 'success',
      timestamp: Date.now(),
      gasUsed: Math.floor(Math.random() * 50000) + 30000,
      blockNumber: Math.floor(Math.random() * 1000000) + 2000000,
      type: 'verifyAssetZKPacked',
      stage: 'stage5',
      verificationResult: true,
      returnValue: '0x0000000000000000000000000000000000000000000000000000000000000001' // true
    };
    
    console.log('✅ [模拟] 零知识证明验证成功:', mockTransaction);
    
    return {
      success: true,
      transaction: mockTransaction
    };
  } else {
    return {
      success: false,
      error: '[模拟] 零知识证明验证失败',
      transaction: {
        contractAddress: WEBASE_CONFIG.contractAddress,
        methodName: 'verifyAssetZKPacked [模拟]',
        status: 'failed',
        timestamp: Date.now(),
        type: 'verifyAssetZKPacked',
        stage: 'stage5',
        verificationResult: false
      }
    };
  }
}

/**
 * 模拟verifyAssetZKPacked调用 (内部版本)
 * @param zkProofData 零知识证明数据
 * @returns 模拟调用结果
 */
async function simulateVerifyAsset(_zkProofData: any): Promise<BlockchainCallResult> {
  console.log('🎭 [模拟] 验证零知识证明...');
  await new Promise(resolve => setTimeout(resolve, 1500 + Math.random() * 500));
  
  // 90% 成功率
  const isSuccess = Math.random() > 0.1;
  
  if (isSuccess) {
    const mockTransaction: BlockchainTransaction = {
      txHash: '0x' + Array.from({length: 64}, () => Math.floor(Math.random() * 16).toString(16)).join(''),
      transactionHash: '0x' + Array.from({length: 64}, () => Math.floor(Math.random() * 16).toString(16)).join(''),
      contractAddress: WEBASE_CONFIG.contractAddress,
      methodName: 'verifyAssetZKPacked [模拟]',
      status: 'success',
      timestamp: Date.now(),
      gasUsed: Math.floor(Math.random() * 50000) + 20000,
      blockNumber: Math.floor(Math.random() * 1000000) + 2000000
    };
    
    console.log('✅ [模拟] 零知识证明验证成功:', mockTransaction);
    
    return {
      success: true,
      transaction: mockTransaction,
      rawResponse: {
        code: 0,
        message: 'success',
        data: mockTransaction
      }
    };
  } else {
    console.log('❌ [模拟] 零知识证明验证失败');
    return {
      success: false,
      error: '模拟：零知识证明验证失败',
      rawResponse: {
        code: -1,
        message: 'ZK verification failed'
      }
    };
  }
}

/**
 * 模拟区块链调用（用于演示模式或作为真实调用的回退）
 * @param zkProofData 零知识证明数据
 * @returns 模拟调用结果
 */
export async function simulateBlockchainCall(_zkProofData: any): Promise<BlockchainCallResult> {
  console.log('🎭 模拟两步区块链调用 (回退模式)...');
  
  // 模拟步骤1: recordAsset
  console.log('📝 [模拟] Step 1: 注册数据资产到区块链...');
  await new Promise(resolve => setTimeout(resolve, 1000 + Math.random() * 500));
  console.log('✅ [模拟] Step 1 成功: 数据资产已注册');
  
  // 模拟步骤2: verifyAssetZKPacked
  console.log('🔍 [模拟] Step 2: 验证零知识证明...');
  await new Promise(resolve => setTimeout(resolve, 1500 + Math.random() * 500));
  
  // 随机模拟成功/失败 (90% 成功率)
  const isSuccess = Math.random() > 0.1;
  
  if (isSuccess) {
    console.log('✅ [模拟] Step 2 成功: 零知识证明验证通过');
    
    const mockTransaction: BlockchainTransaction = {
      txHash: '0x' + Array.from({length: 64}, () => Math.floor(Math.random() * 16).toString(16)).join(''),
      transactionHash: '0x' + Array.from({length: 64}, () => Math.floor(Math.random() * 16).toString(16)).join(''),
      contractAddress: WEBASE_CONFIG.contractAddress,
      methodName: 'recordAsset + verifyAssetZKPacked [模拟]',
      status: 'success',
      timestamp: Date.now(),
      gasUsed: Math.floor(Math.random() * 80000) + 40000, // 两步操作的总Gas
      blockNumber: Math.floor(Math.random() * 1000000) + 2000000
    };
    
    console.log('🎉 [模拟] 两步区块链调用全部成功:', mockTransaction);
    
    return {
      success: true,
      transaction: mockTransaction,
      rawResponse: {
        recordStep: {
          code: 0,
          message: 'success',
          data: {
            transactionHash: '0x' + Array.from({length: 64}, () => Math.floor(Math.random() * 16).toString(16)).join(''),
            gasUsed: Math.floor(Math.random() * 30000) + 20000
          }
        },
        verifyStep: {
          code: 0,
          message: 'success', 
          data: {
            transactionHash: mockTransaction.txHash,
            blockNumber: mockTransaction.blockNumber,
            gasUsed: Math.floor(Math.random() * 50000) + 20000,
            verificationResult: true
          }
        }
      }
    };
  } else {
    console.log('❌ [模拟] Step 2 失败: 零知识证明验证失败');
    
    return {
      success: false,
      error: '模拟：数据已记录但零知识证明验证失败',
      rawResponse: {
        recordStep: {
          code: 0,
          message: 'success',
          data: {
            transactionHash: '0x' + Array.from({length: 64}, () => Math.floor(Math.random() * 16).toString(16)).join(''),
            gasUsed: Math.floor(Math.random() * 30000) + 20000
          }
        },
        verifyStep: {
          code: -1,
          message: 'ZK verification failed'
        }
      }
    };
  }
}

/**
 * 获取交易详情
 * @param txHash 交易哈希
 * @returns 交易详情
 */
export async function getTransactionDetails(txHash: string): Promise<any> {
  try {
    const response = await fetch(`${WEBASE_CONFIG.baseUrl}/trans/handle`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        groupId: WEBASE_CONFIG.groupId,
        txHash: txHash
      })
    });
    
    const data = await response.json();
    return data;
  } catch (error) {
    console.error('获取交易详情失败:', error);
    throw error;
  }
}

/**
 * 自定义合约方法调用
 * @param funcName 方法名称
 * @param funcParam 方法参数
 * @param options 调用选项
 * @returns 调用结果
 */
export async function callCustomContractMethod(
  funcName: string,
  funcParam: string[],
  options: ApiCallOptions = {}
): Promise<BlockchainCallResult> {
  try {
    const result = await webaseApiService.executeApiCall(funcName, funcParam, options);
    return webaseApiService['processApiResponse'](result, funcName);
  } catch (error) {
    return webaseApiService['handleApiError'](error, funcName);
  }
}

/**
 * 添加新的合约方法配置
 * @param methodKey 方法键名
 * @param methodConfig 方法配置
 */
export function addContractMethod(methodKey: string, methodConfig: ContractMethodConfig): void {
  (CONTRACT_METHODS as any)[methodKey] = methodConfig;
}

/**
 * 获取所有可用的合约方法
 * @returns 可用方法列表
 */
export function getAvailableContractMethods(): Array<{ key: string; config: ContractMethodConfig }> {
  return Object.entries(CONTRACT_METHODS).map(([key, config]) => ({ key, config }));
}

/**
 * 验证方法参数
 * @param methodKey 方法键名
 * @param zkProofData 零知识证明数据
 * @returns 验证结果
 */
export function validateMethodParams(methodKey: string, zkProofData: any): { valid: boolean; error?: string } {
  const methodConfig = CONTRACT_METHODS[methodKey];
  if (!methodConfig) {
    return { valid: false, error: `Unknown method: ${methodKey}` };
  }
  
  if (!zkProofData) {
    return { valid: false, error: 'Invalid zkProofData: null or undefined' };
  }
  
  try {
    // 对于recordAsset，我们需要检查dataHash
    if (methodKey === 'recordAsset') {
      const dataHash = zkProofData?.input?.dataHash;
      if (!dataHash) {
        return { valid: false, error: 'Missing dataHash in zkProofData.input' };
      }
    }
    
    // 对于verifyAssetZKPacked，我们需要检查proof数据
    if (methodKey === 'verifyAssetZKPacked') {
      const proof = zkProofData?.proof;
      if (!proof) {
        return { valid: false, error: 'Missing proof data in zkProofData' };
      }
    }
    
    return { valid: true };
  } catch (error) {
    return { 
      valid: false, 
      error: `Parameter validation error: ${error instanceof Error ? error.message : '未知错误'}` 
    };
  }
}
